package mop.model.task.filter;

import java.sql.Timestamp;
import java.util.LinkedList;
import java.util.List;

import mop.model.task.TaskInterface;
import mop.model.task.comparator.TaskDurationComparator;
import mop.util.filter.Filter;
import mop.util.sort.MergeSort;
import mop.util.sort.Sort;

/**
 * Filter on task duration timestamp.
 * 
 * @author	MOP Team 7
 * 
 * @invar hasValidMinMax() == true
 */
public class DurationFilter implements Filter<TaskInterface> 
{
	/**
	 * Constructor.
	 * 
	 * @param 	minimum
	 * 			The minimum duration.
	 * @param 	maximum
	 * 			The maximum duration.

	 * @effect	Minimum is set.
	 * @effect	Maximum is set.
	 */
	public DurationFilter(Timestamp minimum, Timestamp maximum){
		
		if (!isValidMinMax(minimum,maximum))
			throw new IllegalArgumentException("Minimum and maximum are invalid (make sure minimum < maximum)!");
		else
			this.setMinimum(minimum);
			this.setMaximum(maximum);
	}
	
	/**
	 * Check whether min max values are valid
	 */
	public static boolean isValidMinMax(Timestamp min, Timestamp max){
		/* minimum & maximum should be >= 0 */
		if(min.getTime() < 0 || max.getTime() < 0)
			return false;
		
		/* if minimum & maximum is set, maximum >= minimum */
		if(max.getTime() > 0 && min.compareTo(max) >= 0)
			return false;
		
		return true;
	}
	
	/**
	 * Check whether current min max values are valid
	 * @see DurationFilter#isValidMinMax(getMinimum(),getMaximum())
	 */
	public boolean hasValidMinMax(){
		return isValidMinMax(getMinimum(),getMaximum());
	}
	
	/**
	 * The minimum duration.
	 */
	private Timestamp minimum;
	
	/**
	 * Returns the minimum duration.
	 * 
	 * @return	minimum
	 */
	public Timestamp getMinimum()
	{
		return minimum;
	}

	/**
	 * Sets the minimum duration.
	 * 
	 * @param 	minimum
	 * @post 	Minimum is set.
	 */
	private void setMinimum(Timestamp minimum)
	{
		this.minimum = minimum;
	}
	
	/**
	 * The maximum duration.
	 */
	private Timestamp maximum;
	
	/**
	 * Returns the maximum duration.
	 * 
	 * @return	maximum
	 */
	public Timestamp getMaximum()
	{
		return maximum;
	}

	/**
	 * Sets the maximum duration.
	 * 
	 * @param 	maximum
	 * @post 	Maximum is set.
	 */
	private void setMaximum(Timestamp maximum)
	{
		this.maximum = maximum;
	}
	


	/**
	 * Filters the given list of tasks according to their deadline and the given maximum.
	 * 
	 * @param	tasks
	 * 			A list of task interfaces.
	 * @return	List<TaskInterface>
	 * 			A filtered list of task interfaces.
	 */
	@Override
	public List<TaskInterface> filter(List<TaskInterface> list)
	{	
		// make a copy so we don't remove on iterating list
		List<TaskInterface> copy = new LinkedList<TaskInterface>();
		
		for(TaskInterface task : list){
			if(task.getSchedule().getDuration().getTime() >= getMinimum().getTime() && (maximum.getTime() <= 0 || task.getSchedule().getDuration().getTime() <= getMaximum().getTime())){
				copy.add(task);
			}
		}
		
		return copy;
//		copy.addAll(list);
//			
//		
//		int start = -1, stop = -1;
//		// select start & stop
//		for(int i = 0; i < copy.size(); i++)
//		{
//			if(start == -1 && copy.get(i).getSchedule().getDuration().getTime() >= minimum.getTime())
//			{
//				start = i;
//				stop = 0;
//			}
//			if(start > -1 && copy.get(i).getSchedule().getDuration().getTime() <= maximum.getTime())
//			{
//				stop = i;
//			}
//		}
//		
//
//		// if start is below zero, there are no tasks in the selected duration range
//		if(start < 0)
//			return new LinkedList<TaskInterface>();
//		
//		stop = (stop == 0) ? copy.size() - 1 : stop +1; 
//		
//		// otherwise return correct sublist
//		return copy.subList(start, stop+1);
	}
}